package ar.edu.uba.fi.jmit.monitorengine.core.monitor;

import java.util.Date;

import ar.edu.uba.fi.jmit.integrationcommons.Event;
import ar.edu.uba.fi.jmit.integrationcommons.EventPriority;
import ar.edu.uba.fi.jmit.monitorengine.Constants;
import ar.edu.uba.fi.jmit.monitorengine.MonitorEngineTestCase;
import ar.edu.uba.fi.jmit.monitorengine.ResourceProperties;
import ar.edu.uba.fi.jmit.monitorengine.core.ConfigurationManager;
import ar.edu.uba.fi.jmit.monitorengine.mock.ConfigurationManagerMock;
import ar.edu.uba.fi.jmit.monitorengine.mock.MonitorEngineSenderMock;

public class MethodTimeMonitorTestCase extends MonitorEngineTestCase {
	
	@Override
	protected void setUp() throws Exception {
		super.setUp();
		ConfigurationManagerMock.useMockConfigurationManager();
	}
	
	public void testExecuteEvent() {
		MethodTimeMonitor monitor = new MethodTimeMonitor();
		monitor.setMonitorEngineSender(ConfigurationManager.getInstance().getMonitorEngineSender());
		Date date = new Date();
		Event eventFromClient = new Event();
		eventFromClient.setPriority(EventPriority.NORMAL);
		eventFromClient.setSource("MethodTimeMonitorTestCase.testExecuteEvent");
		eventFromClient.addData(ResourceProperties.getProperty("jmit.monitorengine.methodTimeMethodInterceptor.elapsedTime"), 1000);//1 second
		eventFromClient.addData(ResourceProperties.getProperty(Constants.EVENT_MONITOR_NAME_KEY), "monitorName");
		eventFromClient.addData(ResourceProperties.getProperty(Constants.EVENT_MONITOR_DATE), date);
		monitor.execute(eventFromClient);
		Event sendedEvent = ((MonitorEngineSenderMock)monitor.getMonitorEngineSender()).getLastSendedEvent();
		assertEquals(MethodTimeMonitor.class.toString(), sendedEvent.getSource());
		assertEquals(sendedEvent.getPriority(), EventPriority.NORMAL);
		assertEquals(sendedEvent.getData().get(ResourceProperties.getProperty(Constants.METHOD_TIME_ELAPSED_TIME)), 1000L);
		assertEquals(sendedEvent.getData().get(ResourceProperties.getProperty(Constants.METHOD_TIME_AVERAGE)), 1000L);
		
		eventFromClient.addData(ResourceProperties.getProperty("jmit.monitorengine.methodTimeMethodInterceptor.elapsedTime"), 500);//0.5 seconds
		monitor.execute(eventFromClient);
		sendedEvent = ((MonitorEngineSenderMock)monitor.getMonitorEngineSender()).getLastSendedEvent();
		assertEquals(sendedEvent.getData().get(ResourceProperties.getProperty(Constants.METHOD_TIME_ELAPSED_TIME)), 500L);
		assertEquals(sendedEvent.getData().get(ResourceProperties.getProperty(Constants.METHOD_TIME_AVERAGE)), 750L);
		
		eventFromClient.addData(ResourceProperties.getProperty("jmit.monitorengine.methodTimeMethodInterceptor.elapsedTime"), 100);//0.5 seconds
		monitor.execute(eventFromClient);
		sendedEvent = ((MonitorEngineSenderMock)monitor.getMonitorEngineSender()).getLastSendedEvent();
		assertEquals(sendedEvent.getData().get(ResourceProperties.getProperty(Constants.METHOD_TIME_ELAPSED_TIME)), 100L);
		assertEquals(sendedEvent.getData().get(ResourceProperties.getProperty(Constants.METHOD_TIME_AVERAGE)), 533L);
	}
	
	public void testOverflow() {
		long closeToOverflow = (Long.MAX_VALUE / 4L) * 3L;
		for(int j = 100; j <= 10000; j*=10) {
			MethodTimeMonitor monitor = new MethodTimeMonitor();
			monitor.setMonitorEngineSender(ConfigurationManager.getInstance().getMonitorEngineSender());
			long time1 = closeToOverflow / j;
			for(int i = 0; i < 20000; i++) {
				Date date = new Date();
				Event eventFromClient = new Event();
				eventFromClient.setPriority(EventPriority.NORMAL);
				eventFromClient.setSource("MethodTimeMonitorTestCase.testOverflow");
				eventFromClient.addData(ResourceProperties.getProperty("jmit.monitorengine.methodTimeMethodInterceptor.elapsedTime"), time1);
				eventFromClient.addData(ResourceProperties.getProperty(Constants.EVENT_MONITOR_NAME_KEY), "monitorName");
				eventFromClient.addData(ResourceProperties.getProperty(Constants.EVENT_MONITOR_DATE), date);
				monitor.execute(eventFromClient);
				Event sendedEvent = ((MonitorEngineSenderMock)monitor.getMonitorEngineSender()).getLastSendedEvent();
				assertEquals("J: " + j + ", I: " + i + ", time1: " + time1, time1, sendedEvent.getData().get(ResourceProperties.getProperty(Constants.METHOD_TIME_AVERAGE)));
			}
		}
		
		MethodTimeMonitor monitor = new MethodTimeMonitor();
		monitor.setMonitorEngineSender(ConfigurationManager.getInstance().getMonitorEngineSender());
		long time1 = closeToOverflow;
		for(int i = 0; i < 2; i++) {
			Date date = new Date();
			Event eventFromClient = new Event();
			eventFromClient.setPriority(EventPriority.NORMAL);
			eventFromClient.setSource("MethodTimeMonitorTestCase.testOverflow");
			eventFromClient.addData(ResourceProperties.getProperty("jmit.monitorengine.methodTimeMethodInterceptor.elapsedTime"), time1);
			eventFromClient.addData(ResourceProperties.getProperty(Constants.EVENT_MONITOR_NAME_KEY), "monitorName");
			eventFromClient.addData(ResourceProperties.getProperty(Constants.EVENT_MONITOR_DATE), date);
			monitor.execute(eventFromClient);
			Event sendedEvent = ((MonitorEngineSenderMock)monitor.getMonitorEngineSender()).getLastSendedEvent();
			if(i == 0) {
				assertEquals(time1, sendedEvent.getData().get(ResourceProperties.getProperty(Constants.METHOD_TIME_AVERAGE)));
			}else {
				assertEquals(-1L, sendedEvent.getData().get(ResourceProperties.getProperty(Constants.METHOD_TIME_AVERAGE)));
			}
		}
		monitor = new MethodTimeMonitor();
		monitor.setMonitorEngineSender(ConfigurationManager.getInstance().getMonitorEngineSender());
		time1 = closeToOverflow / 10;
		for(int i = 0; i < 11; i++) {
			Date date = new Date();
			Event eventFromClient = new Event();
			eventFromClient.setPriority(EventPriority.NORMAL);
			eventFromClient.setSource("MethodTimeMonitorTestCase.testOverflow");
			eventFromClient.addData(ResourceProperties.getProperty("jmit.monitorengine.methodTimeMethodInterceptor.elapsedTime"), time1);
			eventFromClient.addData(ResourceProperties.getProperty(Constants.EVENT_MONITOR_NAME_KEY), "monitorName");
			eventFromClient.addData(ResourceProperties.getProperty(Constants.EVENT_MONITOR_DATE), date);
			monitor.execute(eventFromClient);
			Event sendedEvent = ((MonitorEngineSenderMock)monitor.getMonitorEngineSender()).getLastSendedEvent();
			if(i < 10) {
				assertEquals(time1, sendedEvent.getData().get(ResourceProperties.getProperty(Constants.METHOD_TIME_AVERAGE)));
			}else {
				assertEquals(-1L, sendedEvent.getData().get(ResourceProperties.getProperty(Constants.METHOD_TIME_AVERAGE)));
			}
		}
		
	}
	
	public void testEventPriority() {
		MethodTimeMonitor monitor = new MethodTimeMonitor();
		monitor.setMonitorEngineSender(ConfigurationManager.getInstance().getMonitorEngineSender());
		Date date = new Date();
		Event eventFromClient = new Event();
		eventFromClient.setPriority(EventPriority.ALERT);
		eventFromClient.setSource("MethodTimeMonitorTestCase.testEventPriority");
		eventFromClient.addData(ResourceProperties.getProperty("jmit.monitorengine.methodTimeMethodInterceptor.elapsedTime"), 1000);//1 second
		eventFromClient.addData(ResourceProperties.getProperty(Constants.EVENT_MONITOR_NAME_KEY), "monitorName");
		eventFromClient.addData(ResourceProperties.getProperty(Constants.EVENT_MONITOR_DATE), date);
		monitor.execute(eventFromClient);
		Event sendedEvent = ((MonitorEngineSenderMock)monitor.getMonitorEngineSender()).getLastSendedEvent();
		assertEquals(MethodTimeMonitor.class.toString(), sendedEvent.getSource());
		assertEquals(sendedEvent.getPriority(), EventPriority.ALERT);
		assertEquals(sendedEvent.getData().get(ResourceProperties.getProperty(Constants.METHOD_TIME_ELAPSED_TIME)), 1000L);
		assertEquals(sendedEvent.getData().get(ResourceProperties.getProperty(Constants.METHOD_TIME_AVERAGE)), 1000L);
		
	}

}
